using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using EzDeploy.Resources;

namespace EzDeploy.Core
{
    public class CopyAssemblyTask : ICopyAssemblyTask
    {
        private readonly ICopyAssemblyCommand _command;

        public CopyAssemblyTask(ICopyAssemblyCommand command)
        {
            _command = command;
        }

        public void Run(Project project, IEnumerable<DeployGridItem> items)
        {
            var args = new TaskExecutingEventArgs();
            this.OnExecuting(args);
            if (args.Cancel)
            {
                this.OnComplete(new Result(ResultType.Canceled, args.Message));
                return;
            }

            if (Directory.Exists(project.DeployedDirectory))
            {
                Result result = null;

                var task = Task.Factory.StartNew(() => result = _command.Run(items, project));
                var waiter = task.GetAwaiter();

                waiter.OnCompleted(() =>
                {
                    if (task.IsFaulted)
                    {
                        if (task.Exception != null)
                        {
                            var ex = task.Exception.GetBaseException();
                            this.OnComplete(new Result(ResultType.Error, ex.Message));
                        }

                        return;
                    }

                    this.OnComplete(result);
                });
            }
            else
                this.OnComplete(new Result(ResultType.Error, MessageResource.DeploymentDirectoryNotFound));
        }

        protected virtual void OnExecuting(TaskExecutingEventArgs args)
        {
            var handler = Executing;
            if (handler != null) handler(this, args);
        }

        protected virtual void OnComplete(Result args)
        {
            var handler = Executed;
            if (handler != null) handler(this, args);
        }

        public event TaskExecutingEventHandler Executing;
        public event TaskExecutedEventHandler Executed;
    }
}
